package com.sxhuayuan.parking.service.impl;

import com.sxhuayuan.parking.compenent.Filter;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.compenent.domain.IdName;
import com.sxhuayuan.parking.config.Platform;
import com.sxhuayuan.parking.dao.BaseDao;
import com.sxhuayuan.parking.dao.OrderDao;
import com.sxhuayuan.parking.dao.ParkChannelDao;
import com.sxhuayuan.parking.dao.ParkingLotDao;
import com.sxhuayuan.parking.dto.PartnerSort;
import com.sxhuayuan.parking.entity.Agent;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.entity.ParkingLotUser;
import com.sxhuayuan.parking.entity.Salesman;
import com.sxhuayuan.parking.service.AgentService;
import com.sxhuayuan.parking.service.ParkingLotService;
import com.sxhuayuan.parking.service.PropService;
import com.sxhuayuan.parking.utils.SettingUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 74172
 */
@Service("parkingLotServiceImpl")
public class ParkingLotServiceImpl extends BaseServiceImpl<ParkingLot, Long> implements ParkingLotService {

	@Autowired
	ParkingLotDao dao;

	@Autowired
	ParkChannelDao parkChannelDao;

	@Resource(name = "agentServiceImpl")
	AgentService agentService;

	@Resource
	OrderDao orderDao;

	@Resource(name = "redisPropServiceImpl")
	PropService propService;

	@Override
	public BaseDao<ParkingLot, Long> getDAO() {
		return dao;
	}

	@Override
	public ParkingLot findBySn(String sn) {
		return dao.findBySn(sn);
	}

	@Override
	public ParkingLot findById(Long id) {
		return dao.findById(id).get();
	}

	@Override
	public void save(ParkingLot entity) {
		entity.setSn(RandomStringUtils.randomNumeric(8).toLowerCase());
		super.save(entity);
	}

	@Override
	public Page<ParkingLot> findPage(Pageable pageable, Agent agent) {

		StringBuilder sb = new StringBuilder("select p from ParkingLot p join AgentRelation r on p.agent=r.child where r.parent.id=").append(agent.getId());
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				setCondition(sb, filter);
			}
		}
		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());

	}

	/** 组装查询条件 */
	private void setCondition(StringBuilder sb, Filter filter) {
		if (filter.getProperty() == null || "".equals(filter.getProperty()) || filter.getValue() == null || "".equals(filter.getValue())) {
			return;
		}
		switch (filter.getProperty()) {

		case "name": {
			sb.append(" and p.name='").append(filter.getValue()).append("' ");
			break;
		}

		case "sn": {
			sb.append(" and p.sn='").append(filter.getValue()).append("' ");
			break;
		}

		case "mchid": {
			sb.append(" and p.mchid='").append(filter.getValue()).append("' ");
			break;
		}

		case "pluginId": {
			sb.append(" and p.pluginId='").append(filter.getValue()).append("' ");
			break;
		}

		case "istartTime": {
			sb.append(" and p.createDate >='").append(filter.getValue()).append("' ");
			break;
		}

		case "iendTime": {
			sb.append(" and p.createDate <='").append(filter.getValue()).append("' ");
			break;
		}

		case "agentId": {
			sb.append(" and p.agent.id='").append(filter.getValue()).append("' ");
			break;
		}

		default:
		}

	}

	@Override
	public void save(ParkingLot parkingLot, Agent agent) {
		Assert.notNull(parkingLot, "");
		parkingLot.setAgent(agent);
		save(parkingLot);
	}

	@Override
	public ParkingLot update(ParkingLot pkLot) {
		/** 判断当前登录的账户是否和要删除的车场 业务人员一直 超级管理员放行 */
		ParkingLot pEntity = dao.findByMyId(pkLot.getId());
		pEntity.setName(pkLot.getName());
		pEntity.setWeixinRate(pkLot.getWeixinRate());
		pEntity.setAlipayRate(pkLot.getAlipayRate());
		pEntity.setAddress(pkLot.getAddress());
		pEntity.setMchid(pkLot.getMchid());
		pEntity.setMchkey(pkLot.getMchkey());
		pEntity.setApiUser(pkLot.getApiUser());
		pEntity.setApiKey(pkLot.getApiKey());
		pEntity.setApiUrl(pkLot.getApiUrl());
		pEntity.setAdvert(pkLot.getAdvert());
		pEntity.setPluginId(pkLot.getPluginId());
		pEntity.setPayMchType(pkLot.getPayMchType());
		pEntity.setIsEnable(pkLot.getIsEnable());
		pEntity.setIsMonthCardChargeEnable(pkLot.getIsMonthCardChargeEnable());
		pEntity.setIsAlipayEnable(pkLot.getIsAlipayEnable());
		pEntity.setIsWeixinEnable(pkLot.getIsWeixinEnable());
		pEntity.setIsPartnerpayEnable(pkLot.getIsPartnerpayEnable());
		pEntity.setIsTcp(pkLot.getIsTcp());
		pEntity.setIsDebug(pkLot.getIsDebug());
		pEntity.setFreeMinutes(pkLot.getFreeMinutes());
		pEntity.setFreeMinutesForLeaving(pkLot.getFreeMinutesForLeaving());
		pEntity.setLotSn(pkLot.getLotSn());
		return dao.save(pEntity);
	}

	/**
	 * 删除车场
	 */
	@Override
	@Transactional
	public void delete(ParkingLot parkingLot) {
		/** 判断当前登录的账户是否和要删除的车场 业务人员一直 超级管理员放行 */
		orderDao.deleteByParkingLotSn(parkingLot.getSn());
		/** 删除所有出口 */
		parkChannelDao.deleteByParkingLot(parkingLot);
		/** 删除车场 */
		dao.delete(parkingLot);
	}

	/**
	 * 删除代理添加的车场
	 */
	@Override
	public void deleteByAgent(Long id) {
		dao.deleteByAgent(id);
	}

	@Override
	public List<ParkingLot> findByAgent(Long id) {
		return dao.findByAgent(id);
	}

	@Override
	public void saveList(List<ParkingLot> list) {
		dao.saveAll(list);
	}

	@Override
	public List<ParkingLot> findList(Agent agent) {
		if (agent != null) {
			// 代理
			return dao.findByAgents(agent);
		}
		// 管理员
		return dao.findAll();
	}

	@Override
	public List<IdName> findSelectOption(Agent agent) {
		if (agent == null) {
			return dao.findAllSelectOption();
		} else {
			return dao.findSelectOptionByAgent(agent.getId());
		}
	}

	@Override
	public Long countAll(Agent agent) {
		if (agent != null) {
			return dao.countByAgent(agent);
		}
		return dao.count();
	}

	@Override
	public void updatePartnersWeight(ParkingLot lot, String partnersWeight) {
		dao.updatePartnersWeight(partnersWeight, lot.getId());
	}

	@Override
	public Platform[] findPreferentialPartnerpayPlatform(ParkingLot lot) {
		if (!lot.getIsPartnerpayEnable()) {
			return null;
		}
		// 查询优先使用的通道，首先是车场配置，其次是平台配置
		Platform[] platforms = null;
		List<PartnerSort> propList = propService.getJsonPropList(String.valueOf(lot.getId()), ParkingLot.PROP_PARTNERS_WEIGHT, PartnerSort.class);
		if (propList != null) {
			List<PartnerSort> collect = propList.stream().sorted(Comparator.comparingInt(PartnerSort::getOrder)).filter((o) -> {
				return o.isEnabled();
			}).collect(Collectors.toList());
			platforms = collect.toArray(new Platform[0]);
		} else {
			platforms = SettingUtils.get().getPartnersWeight();

		}
		return platforms;
	}

	@Override
	public Page<ParkingLot> findPage(Pageable pageable, Salesman salesman) {

		StringBuilder sb = new StringBuilder("select p from ParkingLot p left join Agent a on p.agent.id=a.id where a.salesmanId=").append(salesman.getId());
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				setCondition(sb, filter);
			}
		}
		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());
	}

	@Override
	public Page<ParkingLot> findPageByParkingLotUser(Pageable pageable, ParkingLotUser parkingLotUser) {
		if (parkingLotUser == null || parkingLotUser.getParkingLots().size() <= 0) {
			return new Page<>();
		}
		StringBuilder sb = new StringBuilder("select p from ParkingLot p where");
		Set<ParkingLot> parkingLots = parkingLotUser.getParkingLots();
		List<Long> ids = new ArrayList<>();
		for (ParkingLot parkingLot : parkingLots) {
			ids.add(parkingLot.getId());
		}
		if (ids.size() == 1) {
			sb.append(" p.id=").append(ids.get(0));
		} else {
			sb.append(" p.id in(").append(StringUtils.join(ids.toArray(), ',')).append(") ");
		}
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				setCondition(sb, filter);
			}
		}
		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());
	}
}
